//////////////////////////////////////////////////////////////////////////
//					Character Animation with Direct3D					//
//						   Author: C. Granberg							//
//							   2008 - 2009								//
//////////////////////////////////////////////////////////////////////////

#ifndef SKINNED_MESH
#define SKINNED_MESH

#include <windows.h>
#include <d3dx9.h>
#include <string>
#include <vector>

using namespace std;

#include "bound.h"


struct Bone: public D3DXFRAME
{
    D3DXMATRIX CombinedTransformationMatrix;
};

struct BoneMesh: public D3DXMESHCONTAINER
{
	ID3DXMesh* OriginalMesh;
	vector<D3DMATERIAL9> materials;
	vector<IDirect3DTexture9*> textures;

	DWORD NumAttributeGroups;
	D3DXATTRIBUTERANGE* attributeTable;
	D3DXMATRIX** boneMatrixPtrs;
	D3DXMATRIX* boneOffsetMatrices;
	D3DXMATRIX* currentBoneMatrices;
};

class SkinnedMesh
{
	public:
		SkinnedMesh();
		~SkinnedMesh();
		void Load(IDirect3DDevice9* pDevice, ID3DXEffect* pEffect, char fileName[]);
		void Render(Bone *bone);
		void RenderSkeleton(Bone* bone, Bone *parent, D3DXMATRIX world);

		void SetPose(D3DXMATRIX world, float time);
		void SetAnimation(string name);
		void GetAnimations(vector<string> &animations);

		void genBound()
		{
			m_BoudBox.clear();
			r(m_pRootBone);
		}

		void r(D3DXFRAME* pFrame)
		{
			if( pFrame == NULL)
				return;
			// 
			{
				ID3DXMesh* pMesh;
				if(pFrame->pMeshContainer != NULL)
				{
					pMesh =pFrame->pMeshContainer->MeshData.pMesh;
					cObjectBound BoundBox;
					BoundBox.generate_bound_box(pMesh);
					BoundBox.bound_box_mesh(m_pDevice);
					m_BoudBox.push_back(*BoundBox.get_bound_box());
				}
			}

			if(m_pRootBone->pFrameSibling != NULL)
				r(m_pRootBone->pFrameSibling);

			if(m_pRootBone->pFrameFirstChild != NULL)
				r(m_pRootBone->pFrameFirstChild);
		}
		vector<sBoundBox> m_BoudBox;

	private:
		void UpdateMatrices(Bone* bone, D3DXMATRIX *parentMatrix);
		void SetupBoneMatrixPointers(Bone *bone);

		D3DXFRAME *m_pRootBone;
		ID3DXAnimationController *m_pAnimControl;
		LPD3DXMESH m_pSphereMesh;	
//--
		IDirect3DDevice9* m_pDevice;
		ID3DXEffect *m_pEffect;
};

#endif